package com.leo.common;

import com.leo.bean.EmailInfo;
import com.leo.bean.MessageInfo;
import com.leo.db.DaoMapperProxy;
import com.leo.mapper.UserMapper;
import com.sun.mail.imap.IMAPStore;
import jakarta.mail.*;
import jakarta.mail.internet.MimeMessage;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.*;

/**
 * @author wangss
 * @date 2023/02/22 18:59
 * @description
 **/
@Slf4j
public class MailApiUtil {

    public static final String PATH = "D:\\mail\\";
    private static final String ATTACHMENT_PATH = "D:\\mail\\attachment\\";

    public static void reveiveMail(EmailInfo mailBean) {
        Store store = null;
        Folder folder = null;
        try {
            String type = mailBean.getType();
            if ("pop3".equals(type)) {
                store = getPop3(mailBean);
            } else if ("imap".equals(type)) {
                store = get163Imap(mailBean);
            }
            // 4：获取收件箱内容：（电子邮件）收件箱  folder：邮件夹
            folder = store.getFolder("INBOX");
            // 设置对邮件帐户的访问权限
            // Folder.READ_ONLY (只读或者1)        Folder.READ_WRITE(只写或者2) 以读写模式打开收件箱
            folder.open(Folder.READ_WRITE);

            // 获取邮箱不同状态的邮件
//            Map<String, Integer> mailStatusMap = MailParsingTool.emailInfo(folder);
            int messageCount = folder.getMessageCount();
            int newMessageCount = folder.getNewMessageCount();
            int unreadMessageCount = folder.getUnreadMessageCount();
            UserMapper userMapper = DaoMapperProxy.getProxyInstance(UserMapper.class);
            // 已读邮件数
            int readCount = userMapper.selectMailInfoCount(mailBean.getId());
            log.info("count = {}, newCount = {}, unreadMessageCount = {}, readCount = {}", messageCount, newMessageCount, unreadMessageCount, readCount);
            Message[] messages;
            if (0 >= readCount) {
                // 得到收件箱中的所有邮件,并解析
                messages = folder.getMessages();
            } else {
                if (0 != newMessageCount) {
                    messages = folder.getMessages(messageCount - newMessageCount + 1, messageCount);
                } else if (0 != unreadMessageCount) {
                    messages = folder.getMessages(messageCount - unreadMessageCount + 1, messageCount);
                } else {
                    messages = folder.getMessages(readCount + 1, messageCount);
                }
            }
            parseMessage(mailBean, messages);
        } catch (Exception e) {
            log.error("邮件解析报错：{}", e.getMessage());
        } finally {
            try {
                if (null != folder) {
                    // 关闭邮件夹对象
                    folder.close(false);
                }
                if (null != store) {
                    // 关闭连接对象
                    store.close();
                }
            } catch (Exception e1) {
                log.error("邮件对象关闭失败：{}", e1.getMessage());
            }
        }
    }

    public static Store getPop3(EmailInfo mailBean) throws MessagingException {
        // 1：初始化默认参数
        Properties props = new Properties();
        // 协议
        props.setProperty("mail.store.protocol", mailBean.getType());
        // 端口
        props.setProperty("mail.pop3.port", String.valueOf(mailBean.getReceivePort()));
        // pop3服务器
        props.setProperty("mail.pop3.host", mailBean.getReceiveServer());

        // 2：获取连接
        Session session = Session.getInstance(props);
        // 3：获取Store对象
        Store store = session.getStore(mailBean.getType());
        store.connect(mailBean.getEmail(), mailBean.getPassword());
        return store;
    }

    public static Properties getImap(EmailInfo mailBean) {
        // 1：初始化默认参数
        Properties props = new Properties();
        // 协议
        props.setProperty("mail.store.protocol", mailBean.getType());
        // 端口
        props.setProperty("mail.imap.port", String.valueOf(mailBean.getReceivePort()));
        // 服务器
        props.setProperty("mail.imap.host", mailBean.getReceiveServer());
        props.setProperty("mail.debug.auth", "true");
        props.setProperty("mail.imap.ssl.enable", "true");
        props.setProperty("mail.imap.auth.plain.disable", "true");

        return props;
    }

    public static IMAPStore get163Imap(EmailInfo mailBean) throws MessagingException {
        Properties props = getImap(mailBean);
        Map iam = new HashMap();
        iam.put("name", "myname");
        iam.put("version", "1.0.0");
        iam.put("vendor", "myclient");
        iam.put("support-email", "wangss_kf@163.com");

        // 2：获取连接
        Session session = Session.getInstance(props);
        // 3：获取Store对象
        IMAPStore store = (IMAPStore) session.getStore("imap");
        store.connect(mailBean.getEmail(), mailBean.getPassword());   //POP3服务器登录认证，user我们在properties中已经指定默认
        store.id(iam);
        return store;
    }

    public static Properties getStmp() {
        return null;
    }

    public static boolean checkConnect(EmailInfo mailBean) {
        Store store = null;
        Folder folder = null;
        try {
            String type = mailBean.getType();
            if ("pop3".equals(type)) {
                store = getPop3(mailBean);
            } else if ("imap".equals(type)) {
                store = get163Imap(mailBean);
            }
            return store.isConnected();
        } catch (Exception e) {
            log.error("邮件解析报错：{}", e.getMessage());
            return false;
        } finally {
            try {
                if (null != folder) {
                    // 关闭邮件夹对象
                    folder.close(false);
                }
                if (null != store) {
                    // 关闭连接对象
                    store.close();
                }
            } catch (Exception e1) {
                log.error("邮件对象关闭失败：{}", e1.getMessage());
            }
        }
    }

    public static void parseMessage(EmailInfo mailBean, Message... messages) throws MessagingException, IOException {
        //判断邮件是否为空
        if (messages == null || messages.length < 1) {
            throw new MessagingException("未找到要解析的邮件!");
        }

        UserMapper userMapper = DaoMapperProxy.getProxyInstance(UserMapper.class);

        // 解析所有邮件
        for (int i = 0, count = messages.length; i < count; i++) {
            MimeMessage msg = (MimeMessage) messages[i];
            log.info("-----------解析第" + msg.getMessageNumber() + "封邮件---------------");
            MessageInfo messageInfo = new MessageInfo();
            // 主题
            messageInfo.setSubject(MailParsingTool.getSubject(msg));
            // 发件人
            messageInfo.setEmailFrom(MailParsingTool.getFrom(msg));
            // 收件人
            messageInfo.setEmailReceive(MailParsingTool.getReceiveAddress(msg, Message.RecipientType.TO));
            // 抄送人
            messageInfo.setEmailCc("");
            // 发信时间
            messageInfo.setSendTime(MailParsingTool.getSentDate(msg, "yyyy-MM-dd HH:mm"));
            // 邮件大小
            messageInfo.setEmailSize(msg.getSize() * 1024 + "kb");
            // 是否包含附件
            boolean isContainerAttachment = MailParsingTool.isContainAttachment(msg);
            messageInfo.setIsAttachment(isContainerAttachment ? 1 : 0);
            // 是否已读
            messageInfo.setIsRead(0);
            // 邮件优先级
            messageInfo.setEmailPriority(MailParsingTool.getPriority(msg));
            // 是否需要回执
            messageInfo.setIsReceipt(MailParsingTool.isReplySign(msg) + "");
            // 状态
            messageInfo.setStatus(0);
            // 创建时间
            messageInfo.setCreateTime(new Date());
            // 更新时间
            messageInfo.setUpdateTime(new Date());
            // 邮箱编号
            messageInfo.setEmail_info_id(mailBean.getId());

            // 获取文件的前缀
            String strFile = UUID.randomUUID().toString().replace("-", "").substring(0, 8);
            if (isContainerAttachment) {
                // 附件
                StringBuffer attachmentContent = new StringBuffer();
                // 获取文件的存储目录
                String path = MailApiUtil.class.getClassLoader().getResource("").getPath();
                // 保存附件
                MailParsingTool.saveAttachment(attachmentContent, msg, ATTACHMENT_PATH + strFile + "_");
                // 附件地址
                messageInfo.setAttachmentPath(attachmentContent.toString());
            }
            //用来存储正文的对象
            StringBuffer content = new StringBuffer();
            //处理邮件正文
            MailParsingTool.getMailTextContent(msg, content);
            int index = 0;
            if (content.indexOf("<html") != -1) {
                index = content.indexOf("<html");
            } else if (content.indexOf("<div") != -1) {
                index = content.indexOf("<div");
            } else if (content.toString().startsWith("<")) {
                index = content.indexOf("<");
            }
            // 只获取html部分
            String substring = content.substring(index);
            Files.writeString(Paths.get(PATH + strFile + ".html"), substring);
            // 正文地址
            messageInfo.setContentPath(PATH + strFile + ".html");

            // 入库
            int num = userMapper.insertMessageInfo(messageInfo);
            // 更新收件箱
            ApplicationContentUtil.receiveList.add(messageInfo);
            log.info("-----------第" + msg.getMessageNumber() + "封邮件解析结束------------");
        }
        // 更新主表数量
        userMapper.updateMailInfoCount(messages.length, mailBean.getId());
    }
}
